import React, { useEffect, useRef, useState } from "react";
import {
  Modal,
  ModalContent,
  ModalHeader,
  ModalBody,
  ModalFooter,
  Button,
  useDisclosure,
  Input,
  Select,
  SelectItem,
  Textarea,
  Switch,
} from "@nextui-org/react";
import { showToast } from "../toast";
import { useGlobalState, useHttp } from "@/hooks";
import { App } from "@/entities/App";
import { useRouter } from "next/router";

type Props = {
  size?:
    | "xs"
    | "sm"
    | "md"
    | "lg"
    | "xl"
    | "2xl"
    | "3xl"
    | "4xl"
    | "5xl"
    | "full";
  openCallback?: Fn;
  closeCallback?: Fn;
  confirmCallback?: Fn;
  cancelBtnText?: string;
  confirmBtnText?: string;
  triggerBtnText?: string;
  mode: "create" | "edit";
  endpointId?: number;
  visible?: boolean;
};

const EndpointModal: React.FC<Props> = ({
  size = "3xl",
  openCallback,
  closeCallback,
  triggerBtnText,
  confirmCallback,
  cancelBtnText,
  confirmBtnText,
  mode,
  endpointId,
  visible,
}) => {
  const { isOpen, onOpen, onClose } = useDisclosure();
  const [name, setName] = useState("");
  const [type, setType] = useState("");
  const [value, setValue] = useState("");
  const [isOutputCsv, setIsOutputCsv] = useState(false);
  const [introduce, setIntroduce] = useState("");
  const [app, setApp] = useState("");
  const [appList, setAppList] = useState<
    Array<{ id: number; name: string; introduce: string }>
  >([]);

  const isCreateMode = mode === "create";

  const router = useRouter();
  const datasetid = Number(router.query.datasetid as string);

  useEffect(() => {
    if (visible) {
      handleOpenRef.current();
    }
  }, [visible]);

  const resetInputs = () => {
    setName("");
    setType("");
    setIntroduce("");
    setApp("");
    setValue("");
    setIsOutputCsv(false);
  };

  const getAppList = async (silent = false) => {
    const res = await http.get(
      "/api/app/simpleList",
      {},
      { isOpenLoading: true, silent }
    );
    if (res?.success) {
      setAppList(res.data as App[]);
    }
  };

  const getAppListRef = useRef(getAppList);

  const handleOpen = async () => {
    if (openCallback) {
      openCallback();
    }
    onOpen();

    // getAppListRef.current(true);

    isCreateMode && resetInputs();
    if (!isCreateMode && endpointId) {
      const res = await http.get(
        `/api/endpoint/detail`,
        { endpointid: endpointId },
        { silent: true }
      );
      if (res?.success) {
        setName(res.data.name);
        setType(res.data.type);
        setIntroduce(res.data.introduce);
        setApp(res.data.app);
        setValue(res.data.value);
        setIsOutputCsv(res.data.isOutputCsv);
      }
    }
  };

  const handleOpenRef = useRef(handleOpen);
  handleOpenRef.current = handleOpen;

  const handleClose = () => {
    if (closeCallback) {
      closeCallback();
    }
    onClose();
  };

  useEffect(() => {
    if (endpointId) {
      // get app info
    }
  }, [endpointId]);

  const { isLoading, http } = useHttp();
  // const { id } = useGlobalState('user', 'userInfo')

  const handleConfirm = async () => {
    if (!name) {
      showToast("Please enter endpoint name");
      return;
    }

    if (!introduce) {
      showToast("Please enter endpoint description");
      return;
    }

    if (!type) {
      showToast("Please select endpoint type");
      return;
    }

    if (!value) {
      showToast("Please enter endpoint value");
      return;
    }

    const res = await http.post(
      isCreateMode ? "/api/endpoint/create" : "/api/endpoint/update",
      {
        ...(!isCreateMode ? { endpointid: endpointId } : {}),
        name,
        value,
        type,
        introduce,
        datasetid: datasetid,
        isOutputCsv: isOutputCsv ? 1 : 0,
      }
    );

    if (res?.success) {
      handleClose();
    }

    if (confirmCallback) {
      confirmCallback(res?.success);
    }
  };

  return (
    <div className="create-endpoint-modal">
      {isCreateMode && (
        <Button size="md" radius="md" color="primary" onClick={handleOpen}>
          {triggerBtnText || "Add"}
        </Button>
      )}
      <Modal size={size} isOpen={isOpen} onClose={handleClose}>
        <ModalContent>
          {(onClose) => (
            <>
              <ModalHeader className="flex flex-col gap-1">
                {isCreateMode ? "Create" : "Edit"} Endpoint
              </ModalHeader>
              <ModalBody>
                <div className="flex flex-col gap-4">
                  <div className="control-line">
                    <Input
                      label="Name"
                      size="md"
                      labelPlacement="outside"
                      value={name}
                      onChange={(e) => setName(e.target.value)}
                      className="w-full"
                      isRequired
                      placeholder="Enter endpoint name"
                    />
                  </div>
                  <div className="control-line">
                    <Textarea
                      labelPlacement="outside"
                      isRequired
                      label="Description"
                      placeholder="Enter endpoint description"
                      className="w-full"
                      value={introduce}
                      onChange={(e) => setIntroduce(e.target.value)}
                    />
                  </div>
                  <div className="control-line">
                    <Select
                      labelPlacement="outside"
                      isRequired
                      size="md"
                      selectedKeys={[type]}
                      onChange={(e) => setType(e.target.value)}
                      className="w-full"
                      label="Type"
                      placeholder="Select endpoint type"
                    >
                      <SelectItem key={"query"} value={"query"}>
                        Get List
                      </SelectItem>
                      <SelectItem key={"get"} value={"get"}>
                        Get One
                      </SelectItem>
                      <SelectItem key={"create"} value={"create"}>
                        Create
                      </SelectItem>
                      <SelectItem key={"update"} value={"update"}>
                        Update
                      </SelectItem>
                      <SelectItem key={"delete"} value={"delete"}>
                        Delete
                      </SelectItem>
                    </Select>
                  </div>
                  <div className="control-line">
                    <Textarea
                      labelPlacement="outside"
                      isRequired
                      label="value"
                      placeholder="Enter the mock API, eg: /user/products"
                      className="w-full"
                      value={value}
                      onChange={(e) => setValue(e.target.value)}
                    />
                  </div>
                  <div className="control-line">
                    <Switch
                      isSelected={isOutputCsv ?? false}
                      onValueChange={setIsOutputCsv}
                      size="sm"
                    >
                      Output CSV
                    </Switch>
                    <p className="mt-4 text-gray-500 text-sm">
                      if selected, endpoint will response as a file stream
                    </p>
                  </div>
                </div>
              </ModalBody>
              <ModalFooter>
                <Button
                  isLoading={isLoading}
                  color="primary"
                  onPress={handleConfirm}
                >
                  {confirmBtnText ?? isCreateMode ? "Create" : "Save"}
                </Button>
                <Button color="primary" variant="flat" onPress={onClose}>
                  {cancelBtnText || "Cancel"}
                </Button>
              </ModalFooter>
            </>
          )}
        </ModalContent>
      </Modal>
    </div>
  );
};

export default EndpointModal;
